package hookgen

import (
	"log"
	"os"
	"bytes"
	"text/template"
)

type HookVars struct {
	Imports []string
	Hooks []Hook
}

type Hook struct {
	Name string
	Params string
	Params2 string
	Ret string
	Type string
	Any bool
	MultiHook bool
	Skip bool
	DefaultRet string
	Pure string
}

func AddHooks(add func(name, params, ret, htype string, multiHook, skip bool, defaultRet, pure string)) {
	vhookskip := func(name, params string) {
		add(name,params,"(bool,RouteError)","VhookSkippable_",false,true,"false,nil","")
	}
	vhookskip("forum_check_pre_perms","w http.ResponseWriter,r *http.Request,u *User,fid *int,h *Header")
	vhookskip("router_after_filters","w http.ResponseWriter,r *http.Request,prefix string")
	vhookskip("router_pre_route","w http.ResponseWriter,r *http.Request,u *User,prefix string")
	vhookskip("route_forum_list_start","w http.ResponseWriter,r *http.Request,u *User,h *Header")
	vhookskip("route_topic_list_start","w http.ResponseWriter,r *http.Request,u *User,h *Header")
	vhooknoret := func(name, params string) {
		add(name,params,"","Vhooks",false,false,"false,nil","")
	}
	vhooknoret("router_end","w http.ResponseWriter,r *http.Request,u *User,prefix string, extraData string")
	vhooknoret("topic_reply_row_assign","r *ReplyUser")
	//forums_frow_assign
	//Hook(name string, data interface{}) interface{}
	/*hook := func(name, params, ret, pure string) {
		add(name,params,ret,"Hooks",true,false,ret,pure)
	}*/
	hooknoret := func(name, params string) {
		add(name,params,"","HooksNoRet",true,false,"","")
	}
	hooknoret("forums_frow_assign","f *Forum")
	hookskip := func(name, params string) {
		add(name,params,"(skip bool)","HooksSkip",true,true,"","")
	}
	//hookskip("forums_frow_assign","f *Forum")
	hookskip("topic_create_frow_assign","f *Forum")
	hookss := func(name string) {
		add(name,"d string","string","Sshooks",true,false,"","d")
	}
	hookss("topic_ogdesc_assign")
}

func Write(hookVars HookVars) {
	fileData := `// Code generated by Gosora's Hook Generator. DO NOT EDIT.
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
package common
import ({{range .Imports}}
	"{{.}}"{{end}}
)
{{range .Hooks}}
func H_{{.Name}}_hook(t *HookTable,{{.Params}}) {{.Ret}} { {{if .Any}}
	{{if .MultiHook}}for _, hook := range t.{{.Type}}["{{.Name}}"] {
		{{if .Skip}}if skip = hook({{.Params2}}); skip {
			break
		}{{else}}{{if .Pure}}{{.Pure}} = {{else if .Ret}}return {{end}}hook({{.Params2}}){{end}}
	}{{else}}hook := t.{{.Type}}["{{.Name}}"]
	if hook != nil {
		{{if .Ret}}return {{end}}hook({{.Params2}})
	} {{end}}{{end}}{{if .Pure}}
	return {{.Pure}}{{else if .Ret}}
	return {{.DefaultRet}}{{end}}
}{{end}}
`
	tmpl := template.Must(template.New("hooks").Parse(fileData))
	var b bytes.Buffer
	if e := tmpl.Execute(&b, hookVars); e != nil {
		log.Fatal(e)
	}
	
	err := writeFile("./common/gen_extend.go", string(b.Bytes()))
	if err != nil {
		log.Fatal(err)
	}
}

func writeFile(name, body string) error {
	f, e := os.Create(name)
	if e != nil {
		return e
	}
	if _, e = f.WriteString(body); e != nil {
		return e
	}
	if e = f.Sync(); e != nil {
		return e
	}
	return f.Close()
}